#include "ex14_7.h"
#include <algorithm>
#include <iostream>

std::pair<char *, char *> String::alloc_n_copy(const char *b, const char *e) {
  auto str = alloc.allocate(e - b);
  return {str, std::uninitialized_copy(b, e, str)};
}

void String::range_initializer(const char *first, const char *last) {
  auto newstr = alloc_n_copy(first, last);
  elements = newstr.first;
  end = newstr.second;
}

String::String(const char *s) {
  char *sl = const_cast<char *>(s);
  while (*sl)
    ++sl;
  range_initializer(s, ++sl);
}

String::String(const String &rhs) {
  range_initializer(rhs.elements, rhs.end);
  std::cout << "copy constructor" << std::endl;
}

void String::free() {
  if (elements) {
    std::for_each(elements, end, [this](char &c) { alloc.destroy(&c); });
    alloc.deallocate(elements, end - elements);
  }
}

String::~String() { free(); }

String &String::operator=(const String &rhs) {
  auto newstr = alloc_n_copy(rhs.elements, rhs.end);
  free();
  elements = newstr.first;
  end = newstr.second;
  std::cout << "copy-assignment" << std::endl;
  return *this;
}

std::ostream &operator<<(std::ostream &os, const String &s) {
  char *c = const_cast<char *>(s.c_str());
  while (*c)
    os << *c++;
  return os;
}

int main() {
  String str("Hello World");
  std::cout << str << std::endl;
}